#include	"Compiler.h"
#include	"Config.h"
#include	<vector>
#include	<iostream>
#include	"Object.h"
#include	"CObject.h"

Compiler::Compiler(const Config & config)
	:	m_config(&config)
{
}

Compiler::~Compiler()
{
}

int Compiler::Run()
{
	if(m_config->Logo())
	{
		DisplayLogo();
	}
	if(m_config->Help())
	{
		DisplayHelp();
		return 0;
	}
	std::list< std::string > inputFiles = m_config->Input();
	if(inputFiles.size() > 0)
	{
		if(m_config->Verbose())
		{
			std::cout << "Compiling..." << std::endl;
		}
		for(std::list< std::string >::const_iterator it = inputFiles.begin(); it != inputFiles.end(); ++it)
		{
			Compile(*it);
		}
	}
	else
	{
		throw std::exception("Error: Nothing to compile.");
	}
	return 0;
}

void Compiler::DisplayLogo() const
{
	std::cout << "Mesh Compiler by Erelis team" << std::endl;
	std::cout << "Copyright (c) 2007, Paulius Maruska & Arvydas Nauckunas" << std::endl;
	std::cout << std::endl;
}

void Compiler::DisplayHelp() const
{
	std::cout << "MeshCompiler [options] inputFile1.obj inputFile2.obj ..." << std::endl;
	std::cout << std::endl;
	std::cout << "Available options:" << std::endl;
	std::cout << "  help              - Display this help. (shortcut: h or ?, default: off)." << std::endl;
	std::cout << "  nologo            - Ommit the program logo. (shortcut: l, default: on)." << std::endl;
	std::cout << "  verbose           - Be verbose (generates a lot of output). (shortcut: v, default: off)." << std::endl;
	std::cout << "  check             - Parse the input files (and check if it has any errors)," << std::endl;
	std::cout << "                      but do not generate any output files. (shortcut: c, default: off)." << std::endl;
	std::cout << "  output=<filename> - set the output filename, in cases when you are compiling multiple" << std::endl;
	std::cout << "                      files - be careful with this option. (shortcut: out or o, default: input-basename.cem)." << std::endl;
	std::cout << std::endl;
	std::cout << "Example command lines:" << std::endl;
	std::cout << "  MeshCompiler /help" << std::endl;
	std::cout << "  MeshCompiler cube.obj" << std::endl;
	std::cout << "  MeshCompiler /nologo /output=cube.cem cube.obj" << std::endl;
}

void Compiler::Compile(const std::string & input) const
{
	std::cout << input << std::endl;
	Object object(*m_config);
	object.Load(input);
	CObject co = object.CompiledObject();
	if(m_config->Check())
	{
		return;
	}
	co.SortTriangles();
	co.Save(Output(input));
}

std::string Compiler::Output(const std::string & input) const
{
	std::string output = m_config->Output();
	std::string::size_type lastSlash = input.find_last_of('\\');
	std::string::size_type lastDot = input.find_last_of('.');
	if(output == "")
	{
		output = input.substr(0, lastDot);
		output += ".cem";
	}
	else if(output[output.length() - 1] == '\\')
	{
		output += input.substr(lastSlash + 1, lastDot - lastSlash - 1);
		output += ".cem";
	}
	else if(output.rfind(".cem") != output.length() - 5)
	{
		output += ".cem";
	}
	return output;
}

